grammar XPointer;

options {
	output=AST;
	ASTLabelType=CommonTree;
	language=Java;
	k=2;
}
@header {
	package org.etourdot.xinclude.xpointer;
	
	import java.util.Map;
	import java.util.HashMap;
	import javax.xml.namespace.QName;
	import org.etourdot.xinclude.XIncProcConfiguration;
}
@lexer::header {
	package org.etourdot.xinclude.xpointer;
	
	import java.util.Map;
	import java.util.HashMap;
	import javax.xml.namespace.QName;
}
@members {
private XPointer xpointer = new XPointer();
private Map<String, String> namespaces = new HashMap<String, String>();
private XIncProcConfiguration configuration;

public void setConfiguration(final XIncProcConfiguration configuration) {
this.configuration = configuration;
}

public XPointer getXPointer() {
	return this.xpointer;
}
}


pointer	:	schemebased | shorthand
	;

shorthand
	:	NCNAME 
		{
			xpointer.addPointerPart(configuration.getXPointerEngine().createPointerPart($NCNAME.text));
		}
	;

schemebased
	:	pointerpart (S? pointerpart)*
	;

pointerpart 
	:	schemename
		'(' 
		schemedata
		')'
		{
			xpointer.addPointerPart(configuration.getXPointerEngine().createPointerPart($schemename.qname, $schemedata.text));
		}
	;

schemename returns[QName qname]
	:	prefixedname    { $qname = new QName("", $prefixedname.prefix, $prefixedname.lname); }
	      | unprefixedname  { $qname = new QName($unprefixedname.lname); }
	;

prefixedname returns[String prefix, String lname]
	:	p=NCNAME { $prefix = $p.text; } ':' l=NCNAME { $lname = $l.text; }
	;

unprefixedname returns[String lname]
	:	NCNAME { $lname = $NCNAME.text; }
	;

schemedata
	:	escapeddata*
	;

escapeddata
	:	NORMALCHAR | '\/' | '^(' | '^)' | '^^' | ~('(' | ')' | '^')
	;

NCNAME	: 	NCNAMESTARTCHAR NCNAMECHAR*
	;

fragment NCNAMESTARTCHAR
	: 	('A'..'Z') | '_' | ('a'..'z') | ('\u00C0'..'\u00D6') | ('\u00D8'..'\u00F6') | 
		('\u00F8'..'\u02FF') | ('\u0370'..'\u037D') | ('\u037F'..'\u1FFF') | ('\u200C'..'\u200D') | 
		('\u2070'..'\u218F') | ('\u2C00'..'\u2FEF') | ('\u3001'..'\uD7FF') | ('\uF900'..'\uFDCF') | 
		('\uFDF0'..'\uFFFD')
	;

fragment NCNAMECHAR
	:   	NCNAMESTARTCHAR | '-' | '.' | '0'..'9' | '\u00B7' | '\u0300'..'\u036F' | '\u203F'..'\u2040'
	;

fragment NORMALCHAR
	:	('\u0000'..'\uFFFF')
	;

fragment S	
	:	(' ' | '\t' | '\n' | '\r')+ { skip(); }
	;
